package com.cimp.service.tools.async;

import com.cimp.domain.tools.*;
import com.cimp.util.common.FTPUtil;
import com.cimp.util.common.ShellUtil;
import com.cimp.util.common.svn.SVNManager;
import com.cimp.websocket.UpgradeHandlerProcessor;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * [简要描述]: 一键升级处理线程
 * [详细描述]:
 *
 * @author huojinhao
 * @date 2018/11/15
 */
public class AutoUpgradeRunnable implements Runnable{

    private SVNManager svnManager;

    /**
     * 前台参数
     */
    private UpgradeParam upgradeParam;

    /**
     * 配置参数
     */
    private UpgradeConfig upgradeConfig;

    public AutoUpgradeRunnable(SVNManager svnManager, UpgradeParam upgradeParam, UpgradeConfig upgradeConfig) {
        this.svnManager = svnManager;
        this.upgradeParam = upgradeParam;
        this.upgradeConfig = upgradeConfig;
    }

    @Override
    public void run() {
        try {
            UpgradeHandlerProcessor.sendMessage(UpgradeResult.step(upgradeParam.getStep()));
            // 下载
            String packageFile = null;
            if (UpgradeType.FTP.getValue().equals(upgradeParam.getType())) {
                packageFile = this.ftpDownload();
            } else if (UpgradeType.SVN.getValue().equals(upgradeParam.getType())) {
                packageFile = this.svnDownload();
            }
            // 备份
            this.backUp();
            // 解压
            this.unpack(packageFile);
            // 配置
            this.configPro();
            // 重启
            this.restartApp();
        } catch (Exception e) {
            UpgradeHandlerProcessor.sendMessage(UpgradeResult.error(e.getMessage()));
        }
    }

    /**
     * 重启项目
     */
    private void restartApp() throws Exception {
        ShellUtil.exec(upgradeConfig.getContainer() + "bin/shutdown.sh",null);
        ShellUtil.exec(upgradeConfig.getContainer() + "bin/startup.sh",null);
        this.nextStep();
    }

    /**
     * 配置项目
     */
    private void configPro() throws IOException {
        File root = new File(upgradeConfig.getRootPath());
        FileUtils.forceDelete(root);
        String targetPath = upgradeConfig.getPackagePath() + "iptvcms/webapps/cimp";
        FileUtils.copyDirectory(new File(targetPath), new File(upgradeConfig.getRootPath()));
        if (!new File(upgradeConfig.getRootPath()).exists()) {
            throw new RuntimeException("copy project failed. ???");
        }
        //jdbc.properties
        String jdbcFile = upgradeConfig.getRootPath() + "WEB-INF/classes/jdbc.properties";
        String jdbcContent = FileUtils.readFileToString(new File(jdbcFile), "utf-8");
        jdbcContent = Pattern.compile("bme.url.*").matcher(jdbcContent).replaceFirst("bme.url=" + upgradeConfig.getBmeUrl());
        jdbcContent = Pattern.compile("bme.username.*").matcher(jdbcContent).replaceFirst("bme.username=" + upgradeConfig.getBmeUsername());
        jdbcContent = Pattern.compile("vms.url.*").matcher(jdbcContent).replaceFirst("vms.url=" + upgradeConfig.getVmsUrl());
        jdbcContent = Pattern.compile("vms.username.*").matcher(jdbcContent).replaceFirst("vms.username=" + upgradeConfig.getVmsUsername());
        FileUtils.writeStringToFile(new File(jdbcFile),jdbcContent,"utf-8");
        //web.xml
        String webFile = upgradeConfig.getRootPath() + "WEB-INF/web.xml";
        String webContent = FileUtils.readFileToString(new File(webFile), "utf-8");
        webContent = Pattern.compile("<!-- CsrfSecurityFilter start -->.*?<!-- CsrfSecurityFilter end -->",Pattern.DOTALL).
                matcher(webContent).replaceFirst("");
        FileUtils.writeStringToFile(new File(webFile),webContent,"utf-8");
        //replace jar
        FileUtils.deleteQuietly(new File(upgradeConfig.getRootPath() + "WEB-INF/lib/poi-3.6-20091214.jar"));
        FileUtils.deleteQuietly(new File(upgradeConfig.getRootPath() + "WEB-INF/lib/poi-ooxml-3.9-20121203.jar"));
        FileUtils.deleteQuietly(new File(upgradeConfig.getRootPath() + "WEB-INF/lib/poi-ooxml-schemas-3.9-20121203"));
        FileUtils.deleteQuietly(new File(upgradeConfig.getRootPath() + "WEB-INF/lib/xbean-2.2.0.jar"));
        File descDir = new File(upgradeConfig.getRootPath() + "WEB-INF/lib/");
        FileUtils.copyToDirectory(new File(upgradeConfig.getJarPath() + "poi-3.14.jar"), descDir);
        FileUtils.copyToDirectory(new File(upgradeConfig.getJarPath() + "poi-ooxml-3.14.jar"), descDir);
        FileUtils.copyToDirectory(new File(upgradeConfig.getJarPath() + "poi-ooxml-schemas-3.14.jar"), descDir);
        FileUtils.copyToDirectory(new File(upgradeConfig.getJarPath() + "xmlbeans-2.6.0.jar"), descDir);
        this.nextStep();
    }

    private void backUp() throws Exception {
        String rootPath = upgradeConfig.getRootPath();
        String backupPath = upgradeConfig.getBackupPath();
        if (!new File(rootPath).exists()) {
            throw new RuntimeException("backup failed. " + rootPath + " is not found.");
        }
        if (!new File(backupPath).exists()) {
            if (!new File(backupPath).mkdirs()) {
                throw new RuntimeException("backup failed. " + rootPath + " is not found.");
            }
        }
        String backupFile = backupPath + "backup_" + new SimpleDateFormat("yyyyMMdd_HHmmss")
                .format(new Date()) + ".tar.gz";

        String cmd = "tar zcf " + backupFile + " " + rootPath;
        ShellUtil.exec(cmd , null);
        if (!new File(backupFile).exists()) {
            throw new RuntimeException("backup failed. " + backupFile + " is not found.");
        }
        this.nextStep();
    }


    private void unpack(String packageFile) throws Exception {
        FileUtils.deleteQuietly(new File(upgradeConfig.getPackagePath() + "get_version.sh"));
        FileUtils.forceDelete(new File(upgradeConfig.getPackagePath() + "iptvcms/"));
        FileUtils.forceDelete(new File(upgradeConfig.getPackagePath() + "rccimp"));
        String cmd = "tar zxf " + packageFile;
        ShellUtil.exec(cmd , upgradeConfig.getPackagePath());
        String targetPath = upgradeConfig.getPackagePath() + "iptvcms/webapps/cimp";
        if (!new File(targetPath).exists()) {
            throw new RuntimeException("unpack failed. " + targetPath + " is not found.");
        }

        this.nextStep();
    }

    private String svnDownload() throws Exception {
        // 下载SVN版本包
        svnManager.initialize();
        String packagePath = upgradeConfig.getPackagePath();
        if (!new File(packagePath).exists()) {
            if (!new File(packagePath).mkdirs()) {
                throw new RuntimeException("create package path failed.");
            }
        }
        File svnPath = new File(upgradeParam.getSvnPath());
        String name = svnPath.getName();
        String packageFile = packagePath + name;
        svnManager.getFileFromSVN(upgradeParam.getSvnPath() , packageFile);
        if (!new File(packageFile).exists()) {
            throw new RuntimeException("svn download failed. " + packagePath + " is not found.");
        }
        this.nextStep();
        return packageFile;
    }

    private String ftpDownload() throws Exception {
        String packagePath = upgradeConfig.getPackagePath();
        if (!new File(packagePath).exists()) {
            if (!new File(packagePath).mkdirs()) {
                throw new RuntimeException("create package path failed.");
            }
        }
        String ftpPath = upgradeParam.getFtpPath();
        Pattern pattern = Pattern.compile("ftp://(.+?):(.+?)@(.+?)/(.+?)");
        Matcher matcher = pattern.matcher(ftpPath);
        boolean matches = matcher.matches();
        String username = matcher.group(1);
        String password = matcher.group(2);
        String url = matcher.group(3);
        String target = matcher.group(4);
        File targetFile = new File(target);
        String name = targetFile.getName();
        String packageFile = packagePath + name;
        FTPUtil ftpUtil = new FTPUtil(url, 21, username, password);
        ftpUtil.downLoadFile(target, packageFile);
        return packageFile;
    }

    /**
     * WebSock通知前端 当前进度
     */
    private void nextStep() {
        int step = upgradeParam.getStep();
        upgradeParam.setStep(++step);
        UpgradeHandlerProcessor.sendMessage(UpgradeResult.step(upgradeParam.getStep()));
    }

    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("ftp://(.+?):(.+?)@(.+?)/(.+?)");
        Matcher matcher = pattern.matcher("ftp://user:user@192.168.27.19/xxx.xml");
        int i = matcher.groupCount();
        System.out.println(matcher.matches());
        String group1 = matcher.group(1);
        String group2 = matcher.group(2);
        String group3 = matcher.group(3);
        String group4 = matcher.group(4);
        System.out.println(group1);
        System.out.println(group2);
        System.out.println(group3);
        System.out.println(group4);
    }

}
